package request_models

import (
	"encoding/json"
	"fmt"
	"group-buy/group_buy/internal/common"
	"strconv"

	"github.com/go-resty/resty/v2"
)

type LsPerson struct {
	MchNo          string    `json:"mch_no"`
	AppId          string    `json:"app_id"`
	OrderId        string    `json:"order_id"`
	WayCode        string    `json:"way_code"`
	AccountName    string    `json:"account_name"`
	AccountType    int64     `json:"account_type"`
	AccountAlias   string    `json:"account_alias"`
	DivisionProfit string    `json:"division_profit"`
	ClientIp       string    `json:"client_ip"`
	RelationType   string    `json:"relation_type"`
	ChannelExtra   *UserInfo `json:"channel_extra"`
	ReqTime        int64     `json:"req_time"`
	Version        string    `json:"version"`
	Sign           string    `json:"sign"`
	SignType       string    `json:"sign_type"`
}

func (l *LsPerson) MarshJSON() map[string]string {
	toSerialize := map[string]string{}
	if len(l.MchNo) > 0 {
		toSerialize["mch_no"] = l.MchNo
	}
	if len(l.AppId) > 0 {
		toSerialize["app_id"] = l.AppId
	}
	if len(l.OrderId) > 0 {
		toSerialize["order_id"] = l.OrderId
	}
	if len(l.RelationType) > 0 {
		toSerialize["relation_type"] = l.RelationType
	}
	if len(l.WayCode) > 0 {
		toSerialize["way_code"] = l.WayCode
	}
	if len(l.AccountName) > 0 {
		toSerialize["account_name"] = l.AccountName
	}
	if len(l.AccountAlias) > 0 {
		toSerialize["account_alias"] = l.AccountAlias
	}
	if len(l.DivisionProfit) > 0 {
		toSerialize["division_profit"] = l.DivisionProfit
	}
	if l.AccountType > 0 {
		toSerialize["account_type"] = strconv.FormatInt(l.AccountType, 10)
	}
	if len(l.ClientIp) > 0 {
		toSerialize["client_ip"] = l.ClientIp
	}
	if l.ReqTime > 0 {
		toSerialize["req_time"] = strconv.FormatInt(l.ReqTime, 10)
	}
	if len(l.Version) > 0 {
		toSerialize["version"] = l.Version
	}
	if len(l.Sign) > 0 {
		toSerialize["sign"] = l.Sign
	}
	if len(l.SignType) > 0 {
		toSerialize["sign_type"] = l.SignType
	}
	if l.ChannelExtra != nil {
		//extraMap := l.ChannelExtra.MarshJSON()
		extraStr, _ := json.Marshal(l.ChannelExtra)
		// sortMap := common.SortMaps(extraMap)
		toSerialize["channel_extra"] = string(extraStr)
	}
	return toSerialize
}

type UserInfo struct {
	UserInfo *LsUserInfo `json:"user_info"`
}

type LsUserInfo struct {
	CertType         string `json:"cert_type"`
	Name             string `json:"name"`
	CertNo           string `json:"cert_no"`
	CertValidityType string `json:"cert_validity_type"`
	CertBeginDate    string `json:"cert_begin_date"`
	CertEndDate      string `json:"cert_end_date"`
	MobileNo         string `json:"mobile_no"`
	Email            string `json:"email"`
}

func (l *LsUserInfo) MarshJSON() map[string]string {
	toSerialize := map[string]string{}
	if len(l.CertType) > 0 {
		toSerialize["cert_type"] = l.CertType
	}
	if len(l.Name) > 0 {
		toSerialize["name"] = l.Name
	}
	if len(l.CertNo) > 0 {
		toSerialize["cert_no"] = l.CertNo
	}
	if len(l.CertValidityType) > 0 {
		toSerialize["cert_validity_type"] = l.CertValidityType
	}
	if len(l.CertBeginDate) > 0 {
		toSerialize["cert_begin_date"] = l.CertBeginDate
	}
	if len(l.CertEndDate) > 0 {
		toSerialize["cert_end_date"] = l.CertEndDate
	}
	if len(l.MobileNo) > 0 {
		toSerialize["mobile_no"] = l.MobileNo
	}
	if len(l.Email) > 0 {
		toSerialize["email"] = l.Email
	}
	return toSerialize
}

type LsPersonApplyRsp struct {
	Status int64    `json:"status"`
	Msg    string   `json:"msg"`
	Data   ApplyRsp `json:"data"`
}
type ApplyRsp struct {
	TransStatus string `json:"trans_status"`
	AccountNo   string `json:"account_no"`
	ErrMsg      string `json:"err_msg"`
	RespDesc    string `json:"resp_desc"`
}

func (l *LsPerson) Apply(payKey string) (*LsPersonApplyRsp, error) {
	marshJSON := l.MarshJSON()

	sign := common.Sign(marshJSON, payKey)
	l.Sign = sign

	fmt.Printf("%s\n", l.MarshJSON())
	client := resty.New()
	rsp := &LsPersonApplyRsp{}
	resp, err := client.R().SetBody(l.MarshJSON()).SetResult(rsp).Post("https://api.lspay.tech/gateway/user/personapply")
	if err != nil {
		fmt.Printf("eerrerrrr:%s\n", err)
		return nil, err
	}
	fmt.Printf("%s\n", resp)
	fmt.Printf("%v\n", rsp)
	return rsp, nil
}

type LsConfirm struct {
	MchNo   string `json:"mch_no"`
	AppId   string `json:"app_id"`
	OrderId string `json:"order_id"`
	//ClientIp     string          `json:"client_ip"`
	WayCode      string          `json:"way_code"`
	AccountNo    string          `json:"account_no"`
	ChannelExtra *LsConfirmExtra `json:"channel_extra"`
	ReqTime      int64           `json:"req_time"`
	Version      string          `json:"version"`
	Sign         string          `json:"sign"`
	SignType     string          `json:"sign_type"`
}

func (l *LsConfirm) MarshJSON() map[string]string {
	toSerialize := map[string]string{}
	if len(l.MchNo) > 0 {
		toSerialize["mch_no"] = l.MchNo
	}
	if len(l.AppId) > 0 {
		toSerialize["app_id"] = l.AppId
	}
	if len(l.OrderId) > 0 {
		toSerialize["order_id"] = l.OrderId
	}
	//if len(l.ClientIp) > 0 {
	//	toSerialize["client_ip"] = l.ClientIp
	//}
	if l.ReqTime > 0 {
		toSerialize["req_time"] = strconv.FormatInt(l.ReqTime, 10)
	}
	if len(l.WayCode) > 0 {
		toSerialize["way_code"] = l.WayCode
	}
	if len(l.AccountNo) > 0 {
		toSerialize["account_no"] = l.AccountNo
	}
	if len(l.Version) > 0 {
		toSerialize["version"] = l.Version
	}
	if len(l.Sign) > 0 {
		toSerialize["sign"] = l.Sign
	}
	if len(l.SignType) > 0 {
		toSerialize["sign_type"] = l.SignType
	}
	if l.ChannelExtra != nil {
		//extraMap := l.ChannelExtra.MarshJSON()
		extraStr, _ := json.Marshal(l.ChannelExtra)
		// sortMap := common.SortMaps(extraMap)
		toSerialize["channel_extra"] = string(extraStr)
	}
	return toSerialize
}

type LsConfirmExtra struct {
	CardInfo     *LsCardInfo `json:"card_info"`
	SettleConfig *SettleInfo `json:"settle_config"`
	CashInfo     []*CashInfo `json:"cash_config,omitempty"`
}

//func (l *LsConfirmExtra) MarshJSON() map[string]string {
//	toSerialize := map[string]string{}
//	if len(l.ChannelUser) > 0 {
//		toSerialize["channel_user"] = l.ChannelUser
//	}
//	if len(l.CardInfo.CardNo) > 0 {
//		extraMap := l.CardInfo.MarshJSON()
//		sortMap := common.SortMaps(extraMap)
//		toSerialize["card_info"] = sortMap
//	}
//	return toSerialize
//}

type SettleInfo struct {
	SettleCycle string `json:"settle_cycle"`
}

type CashInfo struct {
	CashType    string `json:"cash_type"`
	SwitchState int64  `json:"switch_state"`
	OutFeeFlag  int64  `json:"out_fee_flag"`
}

type LsCardInfo struct {
	CardType         int64  `json:"card_type,omitempty"`
	CardName         string `json:"card_name"`
	CardNo           string `json:"card_no"`
	ProvId           string `json:"prov_id,omitempty"`
	AreaId           string `json:"area_id,omitempty"`
	BankCode         string `json:"bank_code,omitempty"`
	BranchCode       string `json:"branch_code,omitempty"`
	BranchName       string `json:"branch_name,omitempty"`
	CertType         string `json:"cert_type,omitempty"`
	CertNo           string `json:"cert_no"`
	CertValidityType string `json:"cert_validity_type,omitempty"`
	CertBeginDate    string `json:"cert_begin_date,omitempty"`
	CertEndDate      string `json:"cert_end_date,omitempty"`
	Mp               string `json:"mp"`
}

func (l *LsCardInfo) MarshJSON() map[string]string {
	toSerialize := map[string]string{}
	if l.CardType > 0 {
		//toSerialize["card_type"] = l.CardType
		toSerialize["card_type"] = strconv.FormatInt(l.CardType, 10)
	}
	// if len(l.CertType) > 0 {
	// 	toSerialize["cert_type"] = l.CertType
	// }
	if len(l.CardName) > 0 {
		toSerialize["card_no"] = l.CardName
	}
	if len(l.CardNo) > 0 {
		toSerialize["card_name"] = l.CardNo
	}
	// if len(l.ProvId) > 0 {
	// 	toSerialize["prov_id"] = l.ProvId
	// }
	// if len(l.AreaId) > 0 {
	// 	toSerialize["area_id"] = l.AreaId
	// }
	// if len(l.BranchCode) > 0 {
	// 	toSerialize["branch_code"] = l.BranchCode
	// }
	// if len(l.BranchName) > 0 {
	// 	toSerialize["branch_name"] = l.BranchName
	// }
	if len(l.CertNo) > 0 {
		toSerialize["cert_no"] = l.CertNo
	}
	// if len(l.CertValidityType) > 0 {
	// 	toSerialize["cert_validity_type"] = l.CertValidityType
	// }
	// if len(l.CertBeginDate) > 0 {
	// 	toSerialize["cert_begin_date"] = l.CertBeginDate
	// }
	// if len(l.CertEndDate) > 0 {
	// 	toSerialize["cert_end_date"] = l.CertEndDate
	// }
	if len(l.Mp) > 0 {
		toSerialize["mp"] = l.Mp
	}
	return toSerialize
}

type LsPersonConfirmRsp struct {
	Status int64      `json:"status"`
	Msg    string     `json:"msg"`
	Data   ConfirmRsp `json:"data"`
}
type ConfirmRsp struct {
	TransStatus string `json:"trans_status"`
	AccountNo   string `json:"account_no"`
	RespDesc    string `json:"resp_desc"`
	ErrMsg      string `json:"err_msg,omitempty"`
}

func (l *LsConfirm) Confirm(payKey string) (*LsPersonConfirmRsp, error) {
	//json := l.MarshJSON()
	//sign := common.Sign(json, payKey)
	//l.Sign = sign

	marshJSON := l.MarshJSON()

	sign := common.Sign(marshJSON, payKey)
	l.Sign = sign

	client := resty.New()
	rsp := &LsPersonConfirmRsp{}

	fmt.Printf("1111111111%s\n", l.MarshJSON())
	// b, _ := json.Marshal(l.MarshJSON())
	// fmt.Printf("1111111111%s\n", b)

	// extraStr, _ := json.Marshal(l)

	resp, err := client.R().SetBody(l.MarshJSON()).SetResult(rsp).Post("https://api.lspay.tech/gateway/user/personconfirm")
	fmt.Printf("resp:%s，err:%s\n", resp, err)
	if err != nil {
		fmt.Printf("eerrerrrr:%s\n", err)
		return nil, err
	}
	b, _ := json.Marshal(resp.Request.Body)
	fmt.Printf("resp.Request.Body:%s\n", b)
	fmt.Printf("resp:%s\n", resp)
	fmt.Printf("rsp:%v\n", rsp)
	return rsp, nil
}
